package pl.wroc.pwr.mss.server.ui.tables;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JOptionPane;
import javax.swing.JTable;

import pl.wroc.pwr.mss.logic.domain.Playlist;
import pl.wroc.pwr.mss.logic.domain.Song;
import pl.wroc.pwr.mss.server.exceptions.PlaybackException;
import pl.wroc.pwr.mss.server.ui.dialogs.JSongPlaybackDialog;
import pl.wroc.pwr.mss.server.ui.tables.models.SongTableModel;
import pl.wroc.pwr.mss.server.ui.tables.renderers.SongTableCellRenderer;

/**
 * Tabela przechowujaca dane utworow.
 * 
 * @author mjagus
 */
public class JSongTable extends JTable
{
    /**
     * Identyfikator klasy.
     */
    private static final long serialVersionUID = 6648519372367892343L;

    /**
     * Okno dialogowe do odtwarzania wybranego utworu.
     */
    private JSongPlaybackDialog songPlaybackDialog;

    /**
     * Iniciuje komponent.
     * 
     * @param songTableCellRenderer Wyspecjalizowany renderer tej tabeli
     */
    public JSongTable(SongTableCellRenderer songTableCellRenderer)
    {
        super();

        super.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        super.setDefaultRenderer(String.class, songTableCellRenderer);
        super.addMouseListener(new SongTableMouseAdapter());
    }

    /**
     * Zwraca aktualnie zaznaczony utwor lub <code>null</code> jesli zaden
     * utwor nie jest aktualnie zaznaczony. W przypadku gdy wiele utworow
     * jest zaznaczonych, zwraca pierwszy zaznaczony utwor.
     * 
     * @return Zaznaczony w tabeli utwor
     */
    public Song getSelectedSong()
    {
        int row = super.getSelectedRow();

        if(row != -1)
            return getPlaylist().getSongs().get(row);
        else
            return null;
    }

    /**
     * Zwraca liste wszystkich aktualnie zaznaczonych utworow. W przypadku
     * gdy zaden utwor nie jest zaznaczony, zwraca liste pusta.
     * 
     * @return Lista zaznaczonych utworow
     */
    public List<Song> getSelectedSongs()
    {
        List<Song> songs = new ArrayList<Song>();
        int[] rows = super.getSelectedRows();
        for(int rowIndex : rows)
            songs.add(getPlaylist().getSongs().get(rowIndex));

        return songs;
    }

    /**
     * @return Playlista podpieta do modelu danych tej tabeli
     */
    public Playlist getPlaylist()
    {
        return ((SongTableModel)super.getModel()).getPlaylist();
    }

    /**
     * Podpina nowa playliste pod te tabele i odswieza widok.
     * 
     * @param playlist Nowa playlista, ktora zostanie podpieta do modelu danych
     * tej tabeli
     */
    public void setPlaylist(Playlist playlist)
    {
        SongTableModel model = (SongTableModel)super.getModel();
        model.setPlaylist(playlist);
    }

    /**
     * @return Okno dialogowe do odtwarzania wybranego utworu.
     */
    public JSongPlaybackDialog getSongPlaybackDialog()
    {
        return songPlaybackDialog;
    }

    /**
     * @param songPlaybackDialog Okno dialogowe do odtwarzania wybranego utworu
     */
    public void setSongPlaybackDialog(JSongPlaybackDialog songPlaybackDialog)
    {
        this.songPlaybackDialog = songPlaybackDialog;
    }

    /**
     * Adapter myszy komputerowej nasluchujacy zdarzen na tabeli z utworami.
     * 
     * @author mjagus
     */
    private class SongTableMouseAdapter extends MouseAdapter
    {
        @Override
        public void mouseClicked(MouseEvent e)
        {
            if(e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2)
            {
                try {
                    songPlaybackDialog.supplySong(getSelectedSong());
                    songPlaybackDialog.setVisible(true);
                } catch(PlaybackException ex) {
                    JOptionPane.showMessageDialog(songPlaybackDialog, "Could not open playback dialog. Try again or choose another song.", "Playback error", JOptionPane.ERROR_MESSAGE);
                }
            }
        }
    }
}
